﻿ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using System.Data;
using System.Collections;


namespace BTGISWASECO.Data
{
    /// <summary>
    /// Use DataTableAdapter to fill data in a datatable from a feature cursor
    /// </summary>
    public class DataTableAdapter
    {
        #region =========================== PRIVATE ===============================

        IFeatureCursor cursor;
        ESRI.ArcGIS.Geodatabase.ITable itable; 
        private Hashtable fieldMapping;
        List<DataTable> listTable = new List<DataTable>();
         
        /// <summary>
        ///  Maps the fields of the data table to field indexes in Fields
        /// </summary>
        /// <param name="table"></param>
        private void mapFields(DataTable table)
        {
            fieldMapping = new Hashtable();
            int c = table.Columns.Count;
            int i = 0;
            string s = null;
            int x = 0;
            while (i < c)
            {
                s = table.Columns[i].ColumnName;
                x = cursor.Fields.FindFieldByAliasName(s);
                fieldMapping.Add(s, x);
                i++;
            }
        }

        private void mapFieldsTable(DataTable table)
        {
            fieldMapping = new Hashtable();
            int c = table.Columns.Count;
            int i = 0;
            string s = null;
            int x = 0;
            while (i < c)
            {
                s = table.Columns[i].ColumnName;
                x = itable.Fields.FindFieldByAliasName(s);
                fieldMapping.Add(s, x);
                i++;
            }
        }
        
        /// <summary>
        /// Fills the data table with records
        /// </summary>
        /// <param name="table">data table to be filled</param>
        /// <returns>the number of inserted records</returns>
        private int fillByCursor(DataTable table)
        {
            IFeature feature;
            int count = 0;
            int c = table.Columns.Count;
            int i, x;
            mapFields(table);
            while ((feature = cursor.NextFeature()) != null)
            {
                i = 0;
                DataRow r = table.NewRow();
                while (i < c)
                {
                    string name = table.Columns[i].ColumnName;
                    x = (int)fieldMapping[name];
                    System.Object o = feature.get_Value(x);
                    r[name] = o;
                    i++;
                }
                table.Rows.Add(r);
                count++;
            }
            return count;
        }

        private int fillByTable(DataTable table)
        {
            ESRI.ArcGIS.Geodatabase.IWorkspaceDomains pWSDoms=null;
            ESRI.ArcGIS.Geodatabase.IDomain pDom;
            int count = 0;
            int c = table.Columns.Count;
            int i, x;
            mapFieldsTable(table);
            ESRI.ArcGIS.Geodatabase.IQueryFilter _queryFilter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
            //_queryFilter.WhereClause = "OBJECTID =10";
            _queryFilter.SubFields = "*";
            ESRI.ArcGIS.Geodatabase.IRow row = null;
            ESRI.ArcGIS.Geodatabase.ICursor cursor = itable.Search(_queryFilter, true);
            //pWSDoms = (ESRI.ArcGIS.Geodatabase.IWorkspaceDomains)itable;
            while ((row = cursor.NextRow()) != null)
            {
                i = 0;
                DataRow r = table.NewRow();
                while (i < c)
                {
                    System.Object o=null;
                    string name = table.Columns[i].ColumnName;
                    x = (int)fieldMapping[name];
                    if (row.Fields.get_Field(i).Domain != null)
                    {
                        if (row.get_Value(x) != null)
                        {
                            if (listTable.Count > 0)
                            {
                                bool sosanh = false;
                                for (int t = 0; t < listTable.Count; t++)
                                {
                                    if (listTable[t].TableName == row.Fields.get_Field(i).Domain.Name)
                                    {
                                        sosanh = true;                                       
                                        break;
                                    }
                                }
                                if (sosanh == false)
                                {
                                    listTable.Add(CollectDomainDetails((ESRI.ArcGIS.Geodatabase.IFeatureClass)itable, row.Fields.get_Field(i).Domain.Name));
                                }
                            }
                            else
                                listTable.Add(CollectDomainDetails((ESRI.ArcGIS.Geodatabase.IFeatureClass)itable, row.Fields.get_Field(i).Domain.Name));

                            foreach (DataTable tableDomain in listTable)
                            {
                                if (tableDomain.TableName == row.Fields.get_Field(i).Domain.Name)
                                {
                                    foreach (DataRow rowd in tableDomain.Rows)
                                    {
                                        foreach (DataColumn column in tableDomain.Columns)
                                        {
                                            if (row.get_Value(x).ToString() == rowd[column].ToString())
                                            {
                                                o = rowd["MoTa"];
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            //ESRI.ArcGIS.Geodatabase.ICodedValueDomain codedValueDomain = (ESRI.ArcGIS.Geodatabase.ICodedValueDomain)pDom;                            
                            //o = codedValueDomain.get_Name(Convert.ToInt32(row.get_Value(x))); 
                        }
                        
                    }
                    else
                     o = row.get_Value(x);
                    r[name] = o;
                    i++;
                }
                table.Rows.Add(r);
                count++;
            }
            return count;
        }

        #endregion

        #region =========================== PUBLIC ================================

        

        public DataTableAdapter(IFeatureCursor cursor)
        {
            this.cursor = cursor;
        }



        public DataTableAdapter(ESRI.ArcGIS.Geodatabase.ITable itable)
        {
            this.itable = itable;
        }
        /// <summary>
        /// Fills the data table with records from the supplied cursor
        /// </summary>
        /// <param name="table">data table to be filled</param>
        /// <returns>the number of inserted records</returns>
        public int Fill(DataTable table)
        {
           int c = fillByCursor(table);
           return c; 
        }

        public int FillTable(DataTable table)
        {
            int c = fillByTable(table);
            return c;
        }
        //2605 Rows - 14 Columns
        //======================
        //Fill Blind: 7750 ms
        //Fill: 12359 ms

        public DataTable CollectDomainDetails(ESRI.ArcGIS.Geodatabase.IFeatureClass featureclass,string dmname)
        {
            //Create data table to fill domain details
           // ESRI.ArcGIS.Geodatabase.IWorkspaceDomains pWSDoms;
            ESRI.ArcGIS.Geodatabase.IDomain pDom;
            DataTable dtDomains = CreateDomainTable();
            dtDomains.TableName = dmname;
            IWorkspaceDomains pWorkspaceDomains = (IWorkspaceDomains)(Workspace)featureclass.FeatureDataset.Workspace;
            IFeatureWorkspace pfw = (Workspace)featureclass.FeatureDataset.Workspace as IFeatureWorkspace;
            try
            {
                pDom = pWorkspaceDomains.get_DomainByName(dmname);
                //add each domain to datatable
                if (pDom != null)
                {
                    if (pDom.Type == ESRI.ArcGIS.Geodatabase.esriDomainType.esriDTCodedValue)
                    {
                        ESRI.ArcGIS.Geodatabase.ICodedValueDomain codedValueDomain = (ESRI.ArcGIS.Geodatabase.ICodedValueDomain)pDom;
                        for (int i = 0; i < codedValueDomain.CodeCount; i++)
                        {
                            DataRow cRow = dtDomains.NewRow();
                            cRow["Ma"] = codedValueDomain.get_Value(i).ToString();
                            cRow["MoTa"] = codedValueDomain.get_Name(i);
                            dtDomains.Rows.Add(cRow);
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                //Smooth exit
            }

            return dtDomains;
        }

        private DataTable CreateDomainTable()
        {
            DataTable dtDomains = new DataTable();
            dtDomains.Columns.Add("Ma", typeof(string));
            dtDomains.Columns.Add("Mota", typeof(string));
            return dtDomains;
        }
        #endregion

    }
}
